package com.macro.mall.tiny.common.example;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * @author: i_kun
 * @Desc: o_。
 * @create: 2025-06-25 16:43
 */

public class AESExample {
    // 主方法，程序入口
    public static void main(String[] args) throws Exception {
        // 定义待加密的明文
        String plainText = "Hello, AES Encryption!";
        // 1. 生成AES密钥（128位）
        // 获取AES算法的密钥生成器实例
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        // 初始化密钥长度（128位，可选192/256位）
        keyGen.init(128);
        // 生成密钥对象
        SecretKey secretKey = keyGen.generateKey();
        // 获取密钥的字节数组形式（便于存储或传输）
        byte[] keyBytes = secretKey.getEncoded();
        // 2. 加密
        // 调用自定义加密方法，传入明文和密钥字节数组
        byte[] encryptedData = encrypt(plainText, keyBytes);
        // 将加密结果（字节数组）用Base64编码转换为可打印字符串
        System.out.println("加密结果 (Base64): " + Base64.getEncoder().encodeToString(encryptedData));

        // 3. 解密
        // 调用自定义解密方法，传入密文和密钥字节数组
        String decryptedText = decrypt(encryptedData, keyBytes);
        // 输出解密后的原始明文
        System.out.println("解密结果: " + decryptedText);
    }

    /**
     * AES加密方法
     * @param plainText 待加密的明文
     * @param key 密钥字节数组（长度必须为16/24/32字节，对应128/192/256位）
     * @return 加密后的密文字节数组
     */
    public static byte[] encrypt(String plainText, byte[] key) throws Exception {
        // 将字节数组转换为AES密钥规范对象
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        // 获取AES密码器实例（默认使用ECB模式/PKCS5Padding填充）
        Cipher cipher = Cipher.getInstance("AES");
        // 初始化密码器为加密模式，并传入密钥
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // 执行加密操作：将明文转为UTF-8字节数组，并进行加密
        return cipher.doFinal(plainText.getBytes("UTF-8"));
    }

    /**
     * AES解密方法
     * @param encryptedData 加密后的密文字节数组
     * @param key 密钥字节数组（需与加密时相同）
     * @return 解密后的原始明文字符串
     */
    public static String decrypt(byte[] encryptedData, byte[] key) throws Exception {
        // 重建密钥规范对象
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        // 获取AES密码器实例
        Cipher cipher = Cipher.getInstance("AES");
        // 初始化解密模式
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        // 执行解密操作，获得明文字节数组
        byte[] decryptedBytes = cipher.doFinal(encryptedData);
        // 将字节数组按UTF-8编码转换为字符串
        return new String(decryptedBytes, "UTF-8");
    }
}
